package com.hellobike.haxing.modules.wms.facade.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hellobike.haxing.common.system.vo.LoginUser;
import com.hellobike.haxing.common.util.DateUtils;
import com.hellobike.haxing.modules.shop.entity.Shop;
import com.hellobike.haxing.modules.shop.service.IShopService;
import com.hellobike.haxing.modules.shop.util.PhoneUtils;
import com.hellobike.haxing.modules.wms.dto.*;
import com.hellobike.haxing.modules.wms.entity.*;
import com.hellobike.haxing.modules.wms.enums.PickTypeEnum;
import com.hellobike.haxing.modules.wms.enums.ShippingTypeEnum;
import com.hellobike.haxing.modules.wms.facade.WmsExportFacade;
import com.hellobike.haxing.modules.wms.service.*;
import com.hellobike.haxing.modules.wms.utils.BarCodeUtils;
import com.hellobike.haxing.modules.wms.utils.ListUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component("wmsExportFacade")
public class WmsExportFacadeImpl implements WmsExportFacade {
    @Autowired
    private IAsnHeaderService asnHeaderService;
    @Autowired
    private IDocPutawayService docPutawayService;
    @Autowired
    private IPickHeaderService pickHeaderService;
    @Autowired
    private IShippingHeaderService shippingHeaderService;
    @Autowired
    private IShippingDetailService shippingDetailService;
    @Autowired
    private IDeliveryOrderHeaderService deliveryOrderHeaderService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private IWarehouseService warehouseService;
    @Autowired
    private IReturnWarehouseHeaderService returnWarehouseHeaderService;
    @Autowired
    private IStockBatchLocService stockBatchLocService;
    @Autowired
    private IStockPickService stockPickService;

    @Override
    public List<ExportAsnDto> exportAsn(Long asnId) {
        return asnHeaderService.exportAsn(asnId);
    }

    @Override
    public List<ExportPutawayDto> exportPutaway(Long putawayId) {
        return docPutawayService.exportPutaway(putawayId);
    }

    @Override
    public List<ExportPickKQDto> exportPickKQ(Long id) {
        return pickHeaderService.exportPickKQ(id);
    }

    @Override
    public List<ExportPickZTDDto> exportPickZTD(Long id) {
        return pickHeaderService.exportPickZTD(id);
    }

    @Override
    public Map<String, List<ExportShippingDto>> exportShipping(Long id) {
        Map<String, List<ExportShippingDto>> result = new HashMap<>();
        ShippingHeader shippingHeader = shippingHeaderService.getById(id);
        String date = DateUtils.formatDate(shippingHeader.getCreateTime(), "yyyy-MM-dd HH:mm");
        List<ShippingDetail> details = shippingDetailService.getByHeaderId(id);
        for (ShippingDetail detail : details) {
            DeliveryOrderHeader orderHeader = deliveryOrderHeaderService.getById(detail.getDeliveryHeaderId());
            Shop shop = shopService.getById(orderHeader.getShopId());
            Warehouse warehouse = warehouseService.getById(orderHeader.getWarehouseId());
            List<ExportShippingDto> shippingDtos = shippingHeaderService.exportShipping(orderHeader.getId());
            for (ExportShippingDto shippingDto : shippingDtos) {
                shippingDto.setShippingCode(shippingHeader.getShippingCode());
                shippingDto.setWarehouseName(warehouse.getWarehouseName());
                shippingDto.setShopName(shop.getShopName());
                shippingDto.setDriverName(shippingHeader.getDriverName());
                shippingDto.setDriverTel(shippingHeader.getDriverTel());
                shippingDto.setCarNumber(shippingHeader.getCarNumber());
            }
            String key = date + "-" + shop.getShopName() + "-" + shop.getMobile() + "-" + shop.getAddress();
            if (result.containsKey(key)) {
                key = key + orderHeader.getId();
            }
            result.put(key, shippingDtos);
        }
        return result;
    }

    @Override
    public Map<String, List<ExportReturnShippingDto>> exportReturnShipping(Long id) {
        Map<String, List<ExportReturnShippingDto>> result = new HashMap<>();
        ShippingHeader shippingHeader = shippingHeaderService.getById(id);
        List<ShippingDetail> details = shippingDetailService.getByHeaderId(id);
        for (ShippingDetail detail : details) {
            ReturnWarehouseHeader returnWarehouseHeader = returnWarehouseHeaderService.getById(detail.getDeliveryHeaderId());
            Shop shop = shopService.getById(returnWarehouseHeader.getShopId());
            Warehouse warehouse = warehouseService.getById(returnWarehouseHeader.getWarehouseId());
            List<ExportReturnShippingDto> shippingDtos = shippingHeaderService.exportReturnShipping(returnWarehouseHeader.getId());
            for (ExportReturnShippingDto shippingDto : shippingDtos) {
                shippingDto.setShippingCode(shippingHeader.getShippingCode());
                shippingDto.setWarehouseName(warehouse.getWarehouseName());
                shippingDto.setShopName(shop.getShopName());
                shippingDto.setDriverName(shippingHeader.getDriverName());
                shippingDto.setDriverTel(shippingHeader.getDriverTel());
                shippingDto.setCarNumber(shippingHeader.getCarNumber());
            }
            String key = shop.getShopName() + "-" + shop.getMobile() + "-" + shop.getAddress();
            if (result.containsKey(key)) {
                key = key + returnWarehouseHeader.getId();
            }
            result.put(key, shippingDtos);
        }
        return result;
    }

    @Override
    public List<ExportStockBatchLocDto> exportStockBatchLoc(StockBatchLocDto stockBatchLoc) {
        List<ExportStockBatchLocDto> exportStockBatchLocDtos = stockBatchLocService.exportStockBatchLoc(stockBatchLoc);
        if (ListUtil.isNotEmpty(exportStockBatchLocDtos)) {
            for (ExportStockBatchLocDto exportStockPickDto : exportStockBatchLocDtos) {
                //  { value: 1, desc: '常温' },
                //  { value: 2, desc: '冷藏' },
                //  { value: 3, desc: '冷冻' }
                Integer storeType = exportStockPickDto.getStoreType();
                if (null != storeType) {
                    if (storeType == 1) {
                        exportStockPickDto.setStoreTypeShow("常温");
                    } else if (storeType == 2) {
                        exportStockPickDto.setStoreTypeShow("冷藏");
                    } else if (storeType == 3) {
                        exportStockPickDto.setStoreTypeShow("冷冻");
                    }
                }
            }
        }
        return exportStockBatchLocDtos;
    }

    @Override
    public List<ExportStockPickDto> exportStockPick(StockPickDto stockPick) {
        List<ExportStockPickDto> exportStockPickDtos = stockPickService.exportStockPick(stockPick);
        if (ListUtil.isNotEmpty(exportStockPickDtos)) {
            for (ExportStockPickDto exportStockPickDto : exportStockPickDtos) {
                //  { value: 1, desc: '常温' },
                //  { value: 2, desc: '冷藏' },
                //  { value: 3, desc: '冷冻' }
                Integer storeType = exportStockPickDto.getStoreType();
                if (null != storeType) {
                    if (storeType == 1) {
                        exportStockPickDto.setStoreTypeShow("常温");
                    } else if (storeType == 2) {
                        exportStockPickDto.setStoreTypeShow("冷藏");
                    } else if (storeType == 3) {
                        exportStockPickDto.setStoreTypeShow("冷冻");
                    }
                }
            }
        }
        return exportStockPickDtos;
    }

    @Override
    public Map<String, List<ExportShippingUserInfoDto>> exportShippingUserInfo(Long id) {
        Map<String, List<ExportShippingUserInfoDto>> result = new HashMap<>();
        ShippingHeader shippingHeader = shippingHeaderService.getById(id);
        List<ShippingDetail> details = shippingDetailService.getByHeaderId(id);
        for (ShippingDetail detail : details) {
            DeliveryOrderHeader orderHeader = deliveryOrderHeaderService.getById(detail.getDeliveryHeaderId());
            Shop shop = shopService.getById(orderHeader.getShopId());
//            Warehouse warehouse = warehouseService.getById(orderHeader.getWarehouseId());
            List<ExportShippingUserInfoDto> shippingDtos = shippingHeaderService.exportShippingUserInfo(orderHeader.getId());
            for (ExportShippingUserInfoDto shippingDto : shippingDtos) {
                shippingDto.setShippingHeaderCode(shippingHeader.getShippingCode());
            }
            String key = shop.getShopName();
            if (result.containsKey(key)) {
                key = key + orderHeader.getId();
            }
            result.put(key, shippingDtos);
        }
        return result;
    }

    @Override
    public List<ExportShippingUserInfoDto> exportUserInfo(Long id) {
        ShippingDetail shippingDetail = shippingDetailService.getByDeliveryOrderIdAndType(id, ShippingTypeEnum.SH);
        List<ExportShippingUserInfoDto> exportShippingUserInfoDtos = shippingHeaderService.exportShippingUserInfo(id);
        if (null != shippingDetail) {
            for (ExportShippingUserInfoDto userInfoDto : exportShippingUserInfoDtos) {
                userInfoDto.setShippingHeaderCode(shippingDetail.getShippingHeaderCode());
            }
        }
        return exportShippingUserInfoDtos;
    }

    @Override
    public List<ExportShippingShopPdfDto> exportShippInfo(Long id) {
        List<ShippingDetail> details = shippingDetailService.getByHeaderId(id);
        List<ExportShippingUserInfoDto> exportShippingUserInfoDtos = new ArrayList<>();
        for (ShippingDetail detail : details) {
            DeliveryOrderHeader orderHeader = deliveryOrderHeaderService.getById(detail.getDeliveryHeaderId());
            List<ExportShippingUserInfoDto> shippingDtos = shippingHeaderService.exportShippingUserInfo(orderHeader.getId());
            exportShippingUserInfoDtos.addAll(shippingDtos);
        }
        if (!CollectionUtils.isEmpty(exportShippingUserInfoDtos)) {
            List<Long> shopIdList = exportShippingUserInfoDtos.stream()
                    .map(ExportShippingUserInfoDto::getShopId).collect(Collectors.toList());
            Set<Long> idSet = new HashSet<>();
            idSet.addAll(shopIdList);
            List<Shop> shopList = shopService.list(new QueryWrapper<Shop>().lambda().in(Shop::getId, idSet));
            if (!CollectionUtils.isEmpty(shopList)) {
                Map<Long, Shop> shopMap = shopList.stream().collect(Collectors.toMap(Shop::getId, shop -> shop));
                Map<Long, ExportShippingShopPdfDto> map = new HashMap<>();
                List<ExportShippingShopPdfDto> pdfDtoList = new ArrayList<>();
                Map<String, ExportShippingUserPdfDto> pdfDtoMap = new HashMap<>();
                exportShippingUserInfoDtos.forEach(userInfoDto -> {
                    if (!map.containsKey(userInfoDto.getShopId())) {
                        Shop shop = shopMap.get(userInfoDto.getShopId());
                        if (shop == null) {
                            return;
                        }
                        ExportShippingShopPdfDto pdfDto = new ExportShippingShopPdfDto();
                        pdfDto.setShopId(userInfoDto.getShopId());
                        pdfDto.setShopName(shop.getShopName());
                        pdfDto.setCreateTime(userInfoDto.getCreateTime());
                        pdfDto.setRealName(shop.getRealName());
                        pdfDto.setMobile(shop.getMobile());
                        pdfDto.setPoList(new ArrayList<>());
                        pdfDto.setAddress(shop.getAddress());
                        map.put(userInfoDto.getShopId(), pdfDto);
                        pdfDtoList.add(pdfDto);
                    }
                    ExportShippingShopPdfDto pdfDto = map.get(userInfoDto.getShopId());
                    ExportShippingUserPdfDto userPdfDto = pdfDtoMap.get(userInfoDto.getShopId() + ":" + userInfoDto.getMPhone());
                    if (userPdfDto == null) {
                        userPdfDto = new ExportShippingUserPdfDto();
                        userPdfDto.setMPhone(PhoneUtils.blurPhone(userInfoDto.getMPhone()));
                        userPdfDto.setReceiver(userInfoDto.getReceiver());
                        userPdfDto.setDetails(new ArrayList<>());
                        pdfDto.getPoList().add(userPdfDto);
                        pdfDtoMap.put(userInfoDto.getShopId() + ":" + userInfoDto.getMPhone(), userPdfDto);
                    }
                    ShippingUserDetailPdfDto detailPdfDto = new ShippingUserDetailPdfDto();
                    detailPdfDto.setDimensionValues(userInfoDto.getDimensionValues());
                    detailPdfDto.setNum(userInfoDto.getNum());
                    detailPdfDto.setTitle(userInfoDto.getSpuName());
                    detailPdfDto.setPrice(userInfoDto.getPrice());
                    detailPdfDto.setProductAmount(userInfoDto.getProductAmount());
                    userPdfDto.getDetails().add(detailPdfDto);
                    userPdfDto.setSize(userPdfDto.getDetails().size());
                });
                return pdfDtoList;
            }

        }
        return null;
    }

    @Override
    public List<ExportPickPrintDto> exportPickInfo(String idStr) {
        String[] idArrayStr = idStr.split(",");
        List<ExportPickPrintDto> list = new ArrayList<>();
        for (String idS : idArrayStr) {
            Long id = Long.valueOf(idS);
            PickHeader pickHeader = pickHeaderService.getById(id);
            String type = null;
            String operator = "导出人-";
            try {
                operator = operator + ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
            } catch (Exception ex) {

            }
            ExportPickPrintDto printDto = new ExportPickPrintDto();
            printDto.setDoCode(pickHeader.getDocNo());
            printDto.setOperator(operator);
            printDto.setPoList(new ArrayList<>());
            printDto.setImg(BarCodeUtils.base64(BarCodeUtils.insertWords(BarCodeUtils.getBarCode(pickHeader.getDocNo()), pickHeader.getDocNo())));
            if (PickTypeEnum.KQ.getValue().equals(pickHeader.getPickType())) {
                type = "库区拣货-" + pickHeader.getStoreType() + "-" + pickHeader.getDocNo();
                List<ExportPickKQDto> exportList = exportPickKQ(id);
                if (!CollectionUtils.isEmpty(exportList)) {
                    printDto.setShopName(exportList.get(0).getPartitionCode());
                    exportList.forEach(exportPickKQDto -> {
                        ExportPicPrintDetailDto detailDto = new ExportPicPrintDetailDto();
                        detailDto.setBarcode(exportPickKQDto.getBarcode());
                        detailDto.setDimensionValues(exportPickKQDto.getDimensionValues());
                        detailDto.setPickQty(exportPickKQDto.getPickQty());
                        detailDto.setQty(exportPickKQDto.getQty());
                        detailDto.setTitle(exportPickKQDto.getSpuName());
                        printDto.getPoList().add(detailDto);
                    });
                } else {
                    printDto.setShopName("");
                }
            } else if (PickTypeEnum.ZTD.getValue().equals(pickHeader.getPickType())) {
                type = "自提点拣货-" + pickHeader.getDocNo();
                List<ExportPickZTDDto> exportList = exportPickZTD(id);
                if (!CollectionUtils.isEmpty(exportList)) {
                    printDto.setShopName(exportList.get(0).getShopName());
                    exportList.forEach(pickZTDDto -> {
                        ExportPicPrintDetailDto detailDto = new ExportPicPrintDetailDto();
                        detailDto.setBarcode(pickZTDDto.getBarcode());
                        detailDto.setDimensionValues(pickZTDDto.getDimensionValues());
                        detailDto.setPickQty(pickZTDDto.getPickQty());
                        detailDto.setQty(pickZTDDto.getQty());
                        detailDto.setTitle(pickZTDDto.getSpuName());
                        printDto.getPoList().add(detailDto);
                    });
                } else {
                    printDto.setShopName("");
                }
            }
            type = type + " " + printDto.getShopName();
            printDto.setType(type);
            list.add(printDto);
        }
        return list;
    }

    @Override
    public List<ExportShippingShopPdfDto> exportShippInfo(String idStr) {
        String[] idArrayStr = idStr.split(",");
        List<ExportShippingUserInfoDto> exportShippingUserInfoDtos = new ArrayList<>();
        for (String idS : idArrayStr) {
            Long id = Long.valueOf(idS);
            List<ExportShippingUserInfoDto> exportList = exportUserInfo(id);
            exportShippingUserInfoDtos.addAll(exportList);
        }
        if (!CollectionUtils.isEmpty(exportShippingUserInfoDtos)) {
            List<Long> shopIdList = exportShippingUserInfoDtos.stream()
                    .map(ExportShippingUserInfoDto::getShopId).collect(Collectors.toList());
            Set<Long> idSet = new HashSet<>();
            idSet.addAll(shopIdList);
            List<Shop> shopList = shopService.list(new QueryWrapper<Shop>().lambda().in(Shop::getId, idSet));
            if (!CollectionUtils.isEmpty(shopList)) {
                Map<Long, Shop> shopMap = shopList.stream().collect(Collectors.toMap(Shop::getId, shop -> shop));
                Map<Long, ExportShippingShopPdfDto> map = new HashMap<>();
                Map<String, ExportShippingUserPdfDto> pdfDtoMap = new HashMap<>();
                List<ExportShippingShopPdfDto> pdfDtoList = new ArrayList<>();
                exportShippingUserInfoDtos.forEach(userInfoDto -> {
                    if (!map.containsKey(userInfoDto.getShopId())) {
                        Shop shop = shopMap.get(userInfoDto.getShopId());
                        if (shop == null) {
                            return;
                        }
                        ExportShippingShopPdfDto pdfDto = new ExportShippingShopPdfDto();
                        pdfDto.setShopId(userInfoDto.getShopId());
                        pdfDto.setShopName(shop.getShopName());
                        pdfDto.setCreateTime(userInfoDto.getCreateTime());
                        pdfDto.setRealName(shop.getRealName());
                        pdfDto.setMobile(shop.getMobile());
                        pdfDto.setPoList(new ArrayList<>());
                        pdfDto.setAddress(shop.getAddress());
                        map.put(userInfoDto.getShopId(), pdfDto);
                        pdfDtoList.add(pdfDto);
                    }
                    ExportShippingShopPdfDto pdfDto = map.get(userInfoDto.getShopId());
                    ExportShippingUserPdfDto userPdfDto = pdfDtoMap.get(userInfoDto.getShopId() + ":" + userInfoDto.getMPhone() + ":" + userInfoDto.getReceiver());
                    if (userPdfDto == null) {
                        userPdfDto = new ExportShippingUserPdfDto();
                        userPdfDto.setMPhone(PhoneUtils.blurPhone(userInfoDto.getMPhone()));
                        userPdfDto.setReceiver(userInfoDto.getReceiver());
                        userPdfDto.setDetails(new ArrayList<>());
                        pdfDto.getPoList().add(userPdfDto);
                        pdfDtoMap.put(userInfoDto.getShopId() + ":" + userInfoDto.getMPhone() + ":" + userInfoDto.getReceiver(), userPdfDto);
                    }
                    ShippingUserDetailPdfDto detailPdfDto = new ShippingUserDetailPdfDto();
                    detailPdfDto.setDimensionValues(userInfoDto.getDimensionValues());
                    detailPdfDto.setNum(userInfoDto.getNum());
                    try {
                        pdfDto.setCount(detailPdfDto.getNum() + pdfDto.getCount());
                    } catch (Exception ex) {
                        log.error(JSON.toJSONString(detailPdfDto));
                    }
                    if (userPdfDto.getAmount() == null) {
                        userPdfDto.setAmount(BigDecimal.ZERO);
                    }
                    detailPdfDto.setProductAmount(userInfoDto.getProductAmount());
                    if (detailPdfDto.getProductAmount() == null) {
                        detailPdfDto.setProductAmount(BigDecimal.ZERO);
                    }
                    try {
                        pdfDto.setAmount(detailPdfDto.getProductAmount().add(pdfDto.getAmount()));
                    } catch (Exception ex) {
                        log.info("{}", JSON.toJSONString(detailPdfDto));
                        log.info("{}", JSON.toJSONString(pdfDto.getAmount()));
                        log.error("", ex);
                    }
                    if (StringUtils.isNotBlank(userInfoDto.getDimensionValues())) {
                        detailPdfDto.setTitle(userInfoDto.getSpuName() + " " + userInfoDto.getDimensionValues());
                    } else {
                        detailPdfDto.setTitle(userInfoDto.getSpuName());
                    }
                    detailPdfDto.setPrice(userInfoDto.getPrice());
                    userPdfDto.getDetails().add(detailPdfDto);
                    userPdfDto.setSize(userPdfDto.getDetails().size());
                });
                return pdfDtoList;
            }

        }
        return null;
    }
}
